package versi.vitro.oaiserviceprovider.model;

import static versi.vitro.oaiserviceprovider.helper.Constant.AND_HARVEST_OUT_MODEL_NAME;
import static versi.vitro.oaiserviceprovider.helper.Constant.ANDS_TRIPLES_MODEL_NAME;
import static versi.vitro.oaiserviceprovider.helper.Constant.NEW_ANDS_TRIPLES_MODEL_NAME;
import static versi.vitro.oaiserviceprovider.helper.Constant.TIMESTAMP_MODEL_NAME;
import static versi.vitro.oaiserviceprovider.helper.Constant.ADD_INFO_MODEL_NAME;

import java.util.Arrays;
import java.util.List;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import versi.vitro.oaiserviceprovider.helper.GeneralHelper;
import versi.vitro.oaiserviceprovider.model.AndsExportableModelGeneratorImpl;
import versi.vitro.oaiserviceprovider.service.jena.api.JenaService;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelMaker;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

public class AndsExportableModelGeneratorImplTest {
	
	private Mockery context;

	@BeforeMethod
	public void setUp()
	{
		context = new Mockery();
	}
	
	  @SuppressWarnings("unchecked")
	@Test
	  public void testEnsureModelsExistedWhenAllModelsPresent() {

		  final List<String> modelNames = Arrays.asList(
				  ANDS_TRIPLES_MODEL_NAME, 
				  AND_HARVEST_OUT_MODEL_NAME,
				  NEW_ANDS_TRIPLES_MODEL_NAME,
				  TIMESTAMP_MODEL_NAME,
				  ADD_INFO_MODEL_NAME);

		  final ExtendedIterator<String> extendedIterator = context.mock(ExtendedIterator.class);
		  context.checking(new Expectations() {{
			    exactly(6).of (extendedIterator).hasNext(); will(onConsecutiveCalls(
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(false)
			    		));
			    exactly(5).of (extendedIterator).next(); will(onConsecutiveCalls(
			    		returnValue(modelNames.get(0)),
			    		returnValue(modelNames.get(1)),
			    		returnValue(modelNames.get(2)),
			    		returnValue(modelNames.get(3)),
			    		returnValue(modelNames.get(4))));
			}});
		  
		  final Model model = context.mock(Model.class);
		  context.checking(new Expectations() {{
			  exactly(5).of (model).size(); will(returnValue(0L));
			}});
		  
		  final ModelMaker modelMaker = context.mock(ModelMaker.class);
		  context.checking(new Expectations() {{
			    oneOf (modelMaker).listModels(); will(returnValue(extendedIterator));
			    exactly(5).of (modelMaker).getModel(with(any(String.class))); will(returnValue(model));
			}});
		  
		  final JenaService jenaService = context.mock(JenaService.class);
		  context.checking(new Expectations() {{
			    oneOf (jenaService).getModelMaker(); will(returnValue(modelMaker));
			}});
		  
		  final GeneralHelper generalHelper = context.mock(GeneralHelper.class);
		  context.checking(new Expectations() {{
			    ignoring (generalHelper);
			}});
		  
		  AndsExportableModelGeneratorImpl andsJenaManager = new AndsExportableModelGeneratorImpl(jenaService, generalHelper, null,  "yyyy-dd-MM'T'HH:mm:ssZ", null, null, null, null, null, "FALSE")
		  {
		      protected boolean isDebugEnabled() {
				return true;
			    }
		  };
		  andsJenaManager.ensureModelsExisted();
		  
		  context.assertIsSatisfied();
	  }
		
	  @SuppressWarnings("unchecked")
	@Test
	  public void testEnsureModelsExistedWhenOneModelIsMissing() {

		  final List<String> modelNamesWithOneMissing = Arrays.asList(
				  AND_HARVEST_OUT_MODEL_NAME,
				  NEW_ANDS_TRIPLES_MODEL_NAME,
				  TIMESTAMP_MODEL_NAME,
				  ADD_INFO_MODEL_NAME);

		  final ExtendedIterator<String> extendedIterator = context.mock(ExtendedIterator.class);
		  context.checking(new Expectations() {{
			    exactly(5).of (extendedIterator).hasNext(); will(onConsecutiveCalls(
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(false)
			    		));
			    exactly(4).of (extendedIterator).next(); will(onConsecutiveCalls(
			    		returnValue(modelNamesWithOneMissing.get(0)),
			    		returnValue(modelNamesWithOneMissing.get(1)),
			    		returnValue(modelNamesWithOneMissing.get(2)),
			    		returnValue(modelNamesWithOneMissing.get(3))));
			}});
		  
		  final Model model = context.mock(Model.class);
		  context.checking(new Expectations() {{
			  exactly(4).of (model).size(); will(returnValue(0L));
			}});
		  
		  final ModelMaker modelMaker = context.mock(ModelMaker.class);
		  context.checking(new Expectations() {{
			    oneOf (modelMaker).listModels(); will(returnValue(extendedIterator));
			    exactly(4).of (modelMaker).getModel(with(any(String.class))); will(returnValue(model));
			}});
		  
		  final JenaService jenaService = context.mock(JenaService.class);
		  context.checking(new Expectations() {{
			    oneOf (jenaService).getModelMaker(); will(returnValue(modelMaker));
			    oneOf (jenaService).createModel(ANDS_TRIPLES_MODEL_NAME); 
			}});		  
		  
		  final GeneralHelper generalHelper = context.mock(GeneralHelper.class);
		  context.checking(new Expectations() {{
			    ignoring (generalHelper);
			}});

		  AndsExportableModelGeneratorImpl andsJenaManager = new AndsExportableModelGeneratorImpl(jenaService, generalHelper, null,  "yyyy-dd-MM'T'HH:mm:ssZ", null, null, null, null, null, "FALSE")
		  {
		      protected boolean isDebugEnabled() {
				return true;
			    }
		  };
		  andsJenaManager.ensureModelsExisted();
		  
		  context.assertIsSatisfied();
	  }
		
	  @SuppressWarnings("unchecked")
	@Test
	  public void testEnsureModelsExistedWhenTwoModelsAreMissing() {

		  final List<String> modelNamesWithOneMissing = Arrays.asList(
				  NEW_ANDS_TRIPLES_MODEL_NAME,
				  TIMESTAMP_MODEL_NAME,
				  ADD_INFO_MODEL_NAME);

		  final ExtendedIterator<String> extendedIterator = context.mock(ExtendedIterator.class);
		  context.checking(new Expectations() {{
			    exactly(4).of (extendedIterator).hasNext(); will(onConsecutiveCalls(
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(true),
			    		returnValue(false)
			    		));
			    exactly(3).of (extendedIterator).next(); will(onConsecutiveCalls(
			    		returnValue(modelNamesWithOneMissing.get(0)),
			    		returnValue(modelNamesWithOneMissing.get(1)),
			    		returnValue(modelNamesWithOneMissing.get(2))));
			}});
		  
		  final Model model = context.mock(Model.class);
		  context.checking(new Expectations() {{
			  exactly(3).of (model).size(); will(returnValue(0L));
			}});
		  
		  final ModelMaker modelMaker = context.mock(ModelMaker.class);
		  context.checking(new Expectations() {{
			    oneOf (modelMaker).listModels(); will(returnValue(extendedIterator));
			    exactly(3).of (modelMaker).getModel(with(any(String.class))); will(returnValue(model));
			}});
		  
		  final JenaService jenaService = context.mock(JenaService.class);
		  context.checking(new Expectations() {{
			    oneOf (jenaService).getModelMaker(); will(returnValue(modelMaker));
			    exactly(1).of (jenaService).createModel(ANDS_TRIPLES_MODEL_NAME); 
			    exactly(1).of (jenaService).createModel(AND_HARVEST_OUT_MODEL_NAME); 
			}});
		  
		  final GeneralHelper generalHelper = context.mock(GeneralHelper.class);
		  context.checking(new Expectations() {{
			    ignoring (generalHelper);
			}});
		  
		  AndsExportableModelGeneratorImpl andsJenaManager = new AndsExportableModelGeneratorImpl(jenaService, generalHelper, null,  "yyyy-dd-MM'T'HH:mm:ssZ", null, null, null, null,null, "FALSE")
		  {
		      protected boolean isDebugEnabled() {
				return true;
			    }
		  };
		  andsJenaManager.ensureModelsExisted();
		  
		  context.assertIsSatisfied();
	  }

	  @Test
	  public void testFindDiff() {
		  final JenaService jenaService = context.mock(JenaService.class);
		  context.checking(new Expectations() {{
			    oneOf (jenaService).clearModel(NEW_ANDS_TRIPLES_MODEL_NAME); 
			    oneOf (jenaService).subtractModels(ANDS_TRIPLES_MODEL_NAME, AND_HARVEST_OUT_MODEL_NAME, NEW_ANDS_TRIPLES_MODEL_NAME); 
			}});
		  
		  final GeneralHelper generalHelper = context.mock(GeneralHelper.class);
		  context.checking(new Expectations() {{
			    ignoring (generalHelper);
			}});

		  AndsExportableModelGeneratorImpl andsJenaManager = new AndsExportableModelGeneratorImpl(jenaService, generalHelper, null,  "yyyy-dd-MM'T'HH:mm:ssZ", null, null,null, null, null, "FALSE");

		  
		  andsJenaManager.findDiff();
		  
		  context.assertIsSatisfied();
	  }

	//  @Test
	 /* public void testInsertHarvestedDate() {
		  
		  final String namespaceEtcStr = "namespaceEtc";
		  final String [] sourceModels = 
		  {
					"modelName1",
					"modelName2"
		  };
		  final String destModel = "destinationModelName";
		  
		  final JenaService jenaService = context.mock(JenaService.class);
		  context.checking(new Expectations() {{
			    oneOf (jenaService).renameBlankNode(namespaceEtcStr, sourceModels, destModel); 
			}});
		  
		  final GeneralHelper generalHelper = context.mock(GeneralHelper.class);
		  context.checking(new Expectations() {{
			    ignoring (generalHelper);
			}});

		  AndsExportableModelGeneratorImpl andsJenaManager = new AndsExportableModelGeneratorImpl(jenaService, generalHelper, null, "yyyy-dd-MM'T'HH:mm:ssZ", null, null, null, null, "FALSE");
		  andsJenaManager.insertHarvestedDate(namespaceEtcStr, sourceModels, destModel);
		  
		  context.assertIsSatisfied();
	  }*/

}
